package com.store.service.impl;

import com.store.common.Result;
import com.store.dto.OrderDTO;
import com.store.entity.Order;
import com.store.entity.OrderItem;
import com.store.entity.Product;
import com.store.mapper.OrderMapper;
import com.store.mapper.OrderItemMapper;
import com.store.mapper.ProductMapper;
import com.store.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
    private final OrderMapper orderMapper;
    private final OrderItemMapper orderItemMapper;
    private final ProductMapper productMapper;

    @Override
    public Result getList(Integer pageNum, Integer pageSize, String status) {
        if (pageNum != null && pageSize != null) {
            if (status != null && !status.isEmpty()) {
                return Result.success(orderMapper.selectByStatus(status));
            } else {
                return Result.success(orderMapper.selectList((pageNum - 1) * pageSize, pageSize));
            }
        } else {
            return Result.success(orderMapper.selectAll());
        }
    }

    @Override
    public Result getById(Long id) {
        return Result.success(orderMapper.selectById(id));
    }

    @Override
    public List<Order> getCurrentUserOrders() {
        Long userId = getCurrentUserId();
        return orderMapper.selectByUserId(userId);
    }

    @Override
    @Transactional
    public Result create(OrderDTO orderDTO) {
        Order order = new Order();
        // 设置订单属性
        order.setUserId(orderDTO.getUserId());
        order.setTotalAmount(orderDTO.getTotalAmount());
        order.setStatus("PENDING");
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        
        orderMapper.insert(order);
        return Result.success(order);
    }

    @Override
    @Transactional
    public Result update(OrderDTO orderDTO) {
        Order order = orderMapper.selectById(orderDTO.getOrderId());
        if (order == null) {
            return Result.error(404, "订单不存在");
        }
        
        // 更新订单属性
        order.setStatus(orderDTO.getStatus());
        order.setUpdateTime(LocalDateTime.now());
        
        orderMapper.update(order);
        return Result.success(order);
    }

    @Override
    @Transactional
    public void delete(List<Long> ids) {
        for (Long id : ids) {
            orderMapper.deleteById(id);
        }
    }

    @Override
    @Transactional
    public void updateStatus(Long id, String status) {
        Order order = orderMapper.selectById(id);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        order.setStatus(status);
        order.setUpdateTime(LocalDateTime.now());
        orderMapper.update(order);
    }

    @Override
    public Map<String, Object> getStatistics(String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>();
        result.put("totalOrders", orderMapper.countByDateRange(startDate, endDate));
        result.put("totalSales", orderMapper.calculateSalesByDateRange(startDate, endDate));
        result.put("averageOrderValue", orderMapper.calculateAverageOrderValueByDateRange(startDate, endDate));
        return result;
    }

    @Override
    public Map<String, Object> getDailyStatistics() {
        Map<String, Object> result = new HashMap<>();
        LocalDate today = LocalDate.now();
        result.put("todayOrders", orderMapper.countByDate(today));
        result.put("todaySales", orderMapper.calculateSalesByDate(today));
        return result;
    }

    @Override
    public List<Map<String, Object>> getTopSellingProducts(Integer limit) {
        return orderMapper.selectTopSellingProducts(limit);
    }

    @Override
    public long countAll() {
        return orderMapper.count();
    }

    @Override
    public int countByStatus(String status) {
        return (int) orderMapper.countByStatus(status);
    }

    @Override
    public double calculateTotalSales() {
        return orderMapper.calculateTotalSales().doubleValue();
    }

    @Override
    public List<Order> findRecentOrders(int limit) {
        return orderMapper.selectRecentOrders(limit);
    }

    @Override
    public Map<String, Object> getSalesData(String startDate, String endDate) {
        return orderMapper.selectSalesData(startDate, endDate);
    }

    @Override
    public int countPendingOrders() {
        return countByStatus("PENDING");
    }

    @Override
    public BigDecimal getTodaySales() {
        return orderMapper.selectDailySales(LocalDate.now());
    }

    @Override
    public BigDecimal getMonthlySales(LocalDate date) {
        return orderMapper.selectMonthlySales(date);
    }

    @Override
    public BigDecimal getTotalSales() {
        return orderMapper.calculateTotalSales();
    }

    @Override
    public Product getTopSellingProduct() {
        return orderItemMapper.findTopSellingProduct();
    }

    @Override
    public List<OrderDTO> getOrderList(Integer pageNum, Integer pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Order> orders = orderMapper.selectList(offset, pageSize);
        return orders.stream().map(this::convertToDTO).collect(Collectors.toList());
    }

    @Override
    public List<OrderDTO> getAllOrders() {
        List<Order> orders = orderMapper.selectAll();
        return orders.stream().map(this::convertToDTO).collect(Collectors.toList());
    }

    @Override
    public OrderDTO getOrderById(Long id) {
        Order order = orderMapper.selectById(id);
        return order != null ? convertToDTO(order) : null;
    }

    @Override
    @Transactional
    public OrderDTO createOrder(OrderDTO orderDTO) {
        Order order = convertToEntity(orderDTO);
        
        // 生成订单号
        order.setOrderNo(generateOrderNo());
        // 设置订单状态为待付款
        order.setStatus("PENDING");
        // 设置创建时间和更新时间
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        
        // 计算订单总金额
        BigDecimal totalAmount = order.getProductPrice().multiply(new BigDecimal(order.getQuantity()));
        order.setTotalAmount(totalAmount);
        
        orderMapper.insert(order);
        return convertToDTO(order);
    }

    @Override
    public OrderDTO updateOrder(OrderDTO orderDTO) {
        Order order = convertToEntity(orderDTO);
        orderMapper.update(order);
        return convertToDTO(order);
    }

    @Override
    public void deleteOrders(List<Long> ids) {
        for (Long id : ids) {
            orderMapper.deleteById(id);
        }
    }

    @Override
    @Transactional
    public OrderDTO updateOrderQuantity(Long orderId, Integer quantity) {
        // 1. 验证订单是否存在
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 验证数量是否合法
        if (quantity <= 0) {
            throw new RuntimeException("购买数量必须大于0");
        }

        // 3. 获取商品信息并验证库存
        Product product = productMapper.selectById(order.getProductId());
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        // 计算库存变化
        int stockChange = order.getQuantity() - quantity;
        int newStock = product.getStock() + stockChange;
        if (newStock < 0) {
            throw new RuntimeException("商品库存不足");
        }

        // 4. 更新商品库存
        product.setStock(newStock);
        productMapper.update(product);

        // 5. 更新订单信息
        order.setQuantity(quantity);
        order.setTotalAmount(product.getProductPrice().multiply(new BigDecimal(quantity)));
        order.setUpdateTime(LocalDateTime.now());
        orderMapper.update(order);

        return convertToDTO(order);
    }

    private String generateOrderNo() {
        // 生成订单号：时间戳+4位随机数
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) 
                + String.format("%04d", new Random().nextInt(10000));
    }

    private Long getCurrentUserId() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth == null || "anonymousUser".equals(auth.getName())) {
            throw new RuntimeException("用户未登录");
        }
        return Long.parseLong(auth.getName());
    }

    private OrderDTO convertToDTO(Order order) {
        OrderDTO dto = new OrderDTO();
        BeanUtils.copyProperties(order, dto);
        return dto;
    }

    private Order convertToEntity(OrderDTO dto) {
        Order order = new Order();
        BeanUtils.copyProperties(dto, order);
        return order;
    }
} 